package com.xhwl.logistics.strategy.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xhwl.common.pojo.cent.sdata.Project;
import com.xhwl.common.query.cent.sdata.ProjectQuery;
import com.xhwl.logistics.bo.VehicleCarportBO;
import com.xhwl.logistics.bo.VehicleParkingLotSecondBO;
import com.xhwl.logistics.bo.cent.VehicleIntegratedConfigBO;
import com.xhwl.logistics.bo.input.QueryVehicleCarportBO;
import com.xhwl.logistics.bo.manipulate.VehicleSyncBO;
import com.xhwl.logistics.dao.mapper.IVehicleAreaMapper;
import com.xhwl.logistics.dto.http.*;
import com.xhwl.logistics.entity.*;
import com.xhwl.logistics.service.business.VehicleCommonBusinessService;
import com.xhwl.logistics.service.cent.IProjectService;
import com.xhwl.logistics.service.impl.*;
import com.xhwl.logistics.service.impl.http.LiFangHttpServiceImpl;
import com.xhwl.logistics.strategy.IVehicleParkingLotHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 立方同步车场基本信息的类
 * @Author:wangyiling
 * @Date:2023/04/21
 */
@Slf4j
//@Service
public class VehicleParkingLotLiFangHandlerImpl extends AbstractVehicleParkingLotHandlerImpl implements IVehicleParkingLotHandler {
    @Autowired
    private VehicleParkingLotServiceImpl vehicleParkingLotService;

    @Autowired
    private VehicleAreaServiceImpl vehicleAreaService;

    @Autowired
    private VehicleCardServiceImpl vehicleCardService;

    @Autowired
    private IVehicleAreaMapper vehicleAreaMapper;

    @Autowired
    private VehiclePassageServiceImpl vehiclePassageService;

    @Autowired
    private LiFangHttpServiceImpl liFangHttpService;

    @Autowired
    private IProjectService projectService;
    @Autowired
    private VehicleCommonBusinessService vehicleCommonBusinessService;

    //由于无车场概念，又因为要兼容之前的功能，第三方id不能为空，故parkId为空字符串
    private static final String parkId = "";

    /**
     * 同步立方车场基础信息
     * @param vehicleIntegratedConfigBO
     * @param vehicleSyncBO
     */
    @Override
    public void sync(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, VehicleSyncBO vehicleSyncBO){
        log.info("lifang sync start");
        log.info("vehicleIntegratedConfigBO{}", vehicleIntegratedConfigBO);
        Integer projectId = vehicleIntegratedConfigBO.getVehicleSystemInfoBO().getProjectId();
        ProjectQuery projectQuery = new ProjectQuery();
        List<Integer> ids = new LinkedList<>();
        ids.add(projectId);
        projectQuery.setIds(ids);
        Project project = projectService.getOne(projectQuery, null);
        //如果项目为空，则结束同步程序
        if(project==null){
            return;
        }
        //获取第三方车场信息
        CarSpotStatDaHuaDTO carSpotStatDaHuaDTO = liFangHttpService.getCarSpotStat(vehicleIntegratedConfigBO);

        VehicleParkingLot vehicleParkingLot = vehicleParkingLotService.getOne(new LambdaQueryWrapper<VehicleParkingLot>().eq(VehicleParkingLot::getProjectId, projectId));
        //判断是否已经存在车场信息，存在就进行更新
        if (vehicleParkingLot != null) {
            log.info("lifang ParkingLot Sync Already!");
            vehicleParkingLot.setCarportTotalNumber(carSpotStatDaHuaDTO.getTotalLot());
            vehicleParkingLotService.updateById(vehicleParkingLot);
        }else{
            //查询立方停车场信息，并保存，立方停车场信息无法查询，由于项目默认只有一个停车场，因此用项目名称造个停车场，立方的查询停车场实际是区域信息
            vehicleParkingLot = new VehicleParkingLot();
            vehicleParkingLot.setProjectId(projectId);
            vehicleParkingLot.setCarportTotalNumber(carSpotStatDaHuaDTO.getTotalLot());
            if (project != null){
                vehicleParkingLot.setParkingLotName(project.getName());
            }
            vehicleParkingLot.setParkId(parkId);
            vehicleParkingLotService.save(vehicleParkingLot);
        }

        //同步区域（场区）信息
        syncArea(vehicleIntegratedConfigBO, vehicleParkingLot);

        //同步车场卡类型 暂不同步车场
        //syncCardType(project, vehicleParkingLot);

        log.info("DaHua sync end");

    }

    /**
     * 同步立方区域信息
     * @param vehicleIntegratedConfigBO
     * @param vehicleParkingLot
     */
    private void syncArea(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, VehicleParkingLot vehicleParkingLot){
        //获取区域信息。
        List<ParkingLotAreaInfoDaHuaDTO> parkingLotAreaInfoDaHuaDTO = liFangHttpService.getParkingLotAreaInfo(vehicleIntegratedConfigBO);
        //获取数据库中，该停车场中的所有区域信息。
        List<VehicleArea> vehicleAreaList = vehicleAreaMapper.selectList(new LambdaQueryWrapper<VehicleArea>()
                .eq(VehicleArea::getParkingLotId, vehicleParkingLot.getId()));
        //区域信息和中台的区域信息都不为空
        //注：大华的服务类中已经判空了，如果为空直接返回null
        if(parkingLotAreaInfoDaHuaDTO!=null&&!vehicleAreaList.isEmpty()){
            //根据第三方id建立映射集合,建立大华数据的映射
            List<String> thirdIdFromDaHua = parkingLotAreaInfoDaHuaDTO.stream().map(s -> s.getId()).collect(Collectors.toList());
            Map<String, ParkingLotAreaInfoDaHuaDTO> mapForParkingLotAreaInfoDaHuaDTO = parkingLotAreaInfoDaHuaDTO.stream().collect(Collectors.toMap(s -> {
                return s.getId();
            }, Function.identity()));
            //根据第三方id建立映射集合,建立车行中台数据的映射
            List<String> thirdIdFromCentVehicle = vehicleAreaList.stream().map(s -> s.getThirdAreaId()).collect(Collectors.toList());
            Map<String, VehicleArea> mapForVehicleArea = vehicleAreaList.stream().collect(Collectors.toMap(s -> s.getThirdAreaId(), Function.identity()));
            //获取需要新增的区域信息
            List<String> add = ListUtils.subtract(thirdIdFromDaHua, thirdIdFromCentVehicle);
            //将新增的区域信息存入数据库中
            if(!add.isEmpty()){
                List<ParkingLotAreaInfoDaHuaDTO> parkingLotAreaInfoDaHuaDTOS = add.stream().map(mapForParkingLotAreaInfoDaHuaDTO::get).collect(Collectors.toList());
                List<VehicleArea> vehicleAreas = new LinkedList<>();
                for (ParkingLotAreaInfoDaHuaDTO lotAreaInfoDaHuaDTO : parkingLotAreaInfoDaHuaDTOS) {
                    VehicleArea vehicleArea = new VehicleArea();
                    vehicleArea.setAreaName(lotAreaInfoDaHuaDTO.getParkingLot());
                    vehicleArea.setParkingLotId(vehicleParkingLot.getId());
                    vehicleArea.setCarportTotalNumber(lotAreaInfoDaHuaDTO.getTotalLot());
                    vehicleArea.setThirdAreaId(lotAreaInfoDaHuaDTO.getId());
                    vehicleArea.setRemark(lotAreaInfoDaHuaDTO.getParkingLotCode());
                    vehicleAreas.add(vehicleArea);
                }
                vehicleAreaService.saveBatch(vehicleAreas);
            }
            //获取需要删除的区域信息
            List<String> delete = ListUtils.subtract(thirdIdFromCentVehicle, thirdIdFromDaHua);
            //在数据库中删除需要删除的区域信息
            if(!delete.isEmpty()){
                List<VehicleArea> vehicleAreas = delete.stream().map(mapForVehicleArea::get).collect(Collectors.toList());
                List<Integer> ids = vehicleAreas.stream().map(s -> s.getId()).collect(Collectors.toList());
                vehicleAreaService.removeByIds(ids);
            }
            //获取大华和车行中台中重复的部分
            List<String> same = ListUtils.subtract(thirdIdFromCentVehicle, delete);
            //对相同部分的区域信息进行更新
            if(!same.isEmpty()){
                List<VehicleArea> vehicleAreas = new LinkedList<>();
                for (String thirdId : same) {
                    ParkingLotAreaInfoDaHuaDTO parkingLotAreaInfoDaHuaDTO1 = mapForParkingLotAreaInfoDaHuaDTO.get(thirdId);
                    VehicleArea vehicleArea = mapForVehicleArea.get(thirdId);
                    if(StringUtils.equals(vehicleArea.getAreaName(),parkingLotAreaInfoDaHuaDTO1.getParkingLot())&&StringUtils.equals(vehicleArea.getCarportTotalNumber().toString(),parkingLotAreaInfoDaHuaDTO1.getTotalLot().toString())&&StringUtils.equals(vehicleArea.getRemark(),parkingLotAreaInfoDaHuaDTO1.getParkingLotCode())){
                    }else {
                        vehicleArea.setAreaName(parkingLotAreaInfoDaHuaDTO1.getParkingLot());
                        vehicleArea.setCarportTotalNumber(parkingLotAreaInfoDaHuaDTO1.getTotalLot());
                        vehicleArea.setRemark(parkingLotAreaInfoDaHuaDTO1.getParkingLotCode());
                        vehicleAreas.add(vehicleArea);
                    }
                }
                vehicleAreaService.updateBatchById(vehicleAreas);
            }
        }
        //大华的区域信息为空，中台的区域信息不为空
        else if(parkingLotAreaInfoDaHuaDTO==null&&!vehicleAreaList.isEmpty()){
            List<Integer> ids = vehicleAreaList.stream().map(s -> s.getId()).collect(Collectors.toList());
            vehicleAreaService.removeByIds(ids);
        }
        //大华的区域信息不为空，中台的区域信息为空
        else if(parkingLotAreaInfoDaHuaDTO!=null&&vehicleAreaList.isEmpty()){
            LinkedList<VehicleArea> vehicleAreas = new LinkedList<>();
            for (ParkingLotAreaInfoDaHuaDTO lotAreaInfoDaHuaDTO : parkingLotAreaInfoDaHuaDTO) {
                VehicleArea vehicleArea = new VehicleArea();
                vehicleArea.setAreaName(lotAreaInfoDaHuaDTO.getParkingLot());
                vehicleArea.setParkingLotId(vehicleParkingLot.getId());
                vehicleArea.setCarportTotalNumber(lotAreaInfoDaHuaDTO.getTotalLot());
                vehicleArea.setThirdAreaId(lotAreaInfoDaHuaDTO.getId());
                vehicleArea.setRemark(lotAreaInfoDaHuaDTO.getParkingLotCode());
                vehicleAreas.add(vehicleArea);
            }
            vehicleAreaService.saveBatch(vehicleAreas);
        }

        //获取同步好的区域信息
        List<VehicleArea> vehicleAreas = vehicleAreaMapper.selectList(new LambdaQueryWrapper<VehicleArea>()
                .eq(VehicleArea::getParkingLotId, vehicleParkingLot.getId()));
        //同步大华的通道信息
        for (VehicleArea vehicleArea : vehicleAreas) {
            syncPassage(vehicleIntegratedConfigBO,vehicleParkingLot,vehicleArea.getThirdAreaId(),vehicleArea.getId(), vehicleArea.getRemark());
        }
    }

    /**
     * 同步大华通道信息和设备信息
     * @param vehicleIntegratedConfigBO
     * @param vehicleParkingLot
     */
    private void syncPassage(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, VehicleParkingLot vehicleParkingLot, String parkingLotId, Integer areaId, String areaCode){
        List<VehiclePassage> vehiclePassageThirdList = new LinkedList<>();

        //获取大华下该区域的所有通道信息
        List<PassageAndDeviceDaHuaDTO> passageAndDeviceDaHuaDTOS = liFangHttpService.getPassageList(vehicleIntegratedConfigBO);
        //获取车行中台下该区域的所有通道信息
        List<VehiclePassage> vehiclePassageList = vehiclePassageService.list(new LambdaQueryWrapper<VehiclePassage>().eq(VehiclePassage::getAreaId, areaId).eq(VehiclePassage::getProjectId,vehicleParkingLot.getProjectId()));
        if(passageAndDeviceDaHuaDTOS != null) {
            for (PassageAndDeviceDaHuaDTO passageAndDeviceDaHuaDTO : passageAndDeviceDaHuaDTOS) {
                VehiclePassage vehiclePassage = new VehiclePassage();
                vehiclePassage.setPassageName(passageAndDeviceDaHuaDTO.getTideName());
                vehiclePassage.setType(Integer.parseInt(passageAndDeviceDaHuaDTO.getCarDirect()));
                vehiclePassage.setProjectId(vehicleParkingLot.getProjectId());
                vehiclePassage.setParkingLotId(vehicleParkingLot.getId());
                vehiclePassage.setAreaId(areaId);
                vehiclePassage.setThirdPassageId(passageAndDeviceDaHuaDTO.getChannelId());
                vehiclePassageThirdList.add(vehiclePassage);
            }
        }
        vehicleCommonBusinessService.syncPassage(vehiclePassageList, vehiclePassageThirdList);
    }

    /**
     * 立方无车卡类型 默认建一个
     * @param project
     * @param vehicleParkingLot
     */
    private void syncCardType(Project project, VehicleParkingLot vehicleParkingLot){
        //查询车行中台的卡类型信息
        List<VehicleCard> vehicleCardList = vehicleCardService.list(new LambdaQueryWrapper<VehicleCard>().eq(VehicleCard::getProjectId, project.getId()).eq(VehicleCard::getParkingLotId, vehicleParkingLot.getId()));
        //如果车行中台的卡类型为空 默认建一个月租卡类型
        if (vehicleCardList.isEmpty()){
            VehicleCard vehicleCard = new VehicleCard();
            vehicleCard.setProjectId(project.getId());
            vehicleCard.setProjectName(project.getName());
            vehicleCard.setParkingLotId(vehicleParkingLot.getId());
            vehicleCard.setParkingLotName(vehicleParkingLot.getParkingLotName());
            vehicleCard.setName("免费卡");
            vehicleCard.setCardType(0);
            vehicleCardService.save(vehicleCard);
        }
    }

    @Override
    public VehicleCarportBO queryCarport(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, QueryVehicleCarportBO queryVehicleCarportBO) {
        VehicleCarportBO vehicleCarportBO = new VehicleCarportBO();
        //获取第三方车场信息
        CarSpotStatDaHuaDTO carSpotStatDaHuaDTO = liFangHttpService.getCarSpotStat(vehicleIntegratedConfigBO);
        vehicleCarportBO.setTotalNumber(carSpotStatDaHuaDTO.getTotalLot());
        vehicleCarportBO.setFreeNumber(carSpotStatDaHuaDTO.getIdleLot());
        return vehicleCarportBO;
    }

    @Override
    protected List<VehicleParkingLotSecondBO> queryParkingLots(Integer projectId, String parkingLotName){
        return new ArrayList<>();
    }

    @Override
    protected VehicleParkingLotSecondBO queryParkingLot(Integer projectId){
        return new VehicleParkingLotSecondBO();
    }

    @Override
    protected VehicleCarportBO getVehicleCarportBOFromHttp(VehicleIntegratedConfigBO vehicleIntegratedConfigBO){
        return new VehicleCarportBO();
    }

    @Override
    protected Integer statisticsEnterCount(Integer projectId, String parkId, Date ingestionDate){
        return 0;
    }

    @Override
    protected Integer statisticsGoOutCount(Integer projectId, String parkId, Date ingestionDate){
        return 0;
    }

    @Override
    protected void pushDwsAccessRecordForHourDataToCentBi(Integer projectId, String parkingLotName,
                                                          Integer totalForCount, Integer enterForCount, Integer goOutForCount,
                                                          Date processDate, Date ingestionDate){

    }

    @Override
    protected Integer statisticsTotalPaySum(Integer projectId, String parkId, Date ingestionDate){
        return 0;
    }

    @Override
    protected void pushDwsPayRecordForHourDataToCentBi(Integer projectId, String parkingLotName,
                                                       Integer totalPay, Integer webChatPay, Integer aliPay, Integer onlinePay, Integer other,
                                                       Date processDate, Date ingestionDate){

    }

    /**
     * 访客车预约新增
     */
    @Override
    public String reserverSpace(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, com.xhwl.common.vo.cent.vehicle.CarVO carVO) {
        String orederNo = "";
        return orederNo;
    }

    /**
     * 访客车预约取消
     */
    @Override
    public void cancelReserve(VehicleIntegratedConfigBO vehicleIntegratedConfigBO, String orderNo) {
    }

}
